package reflects

import (
	"errors"
	"reflect"
)

func IterateFields(entity any) (map[string]any, error) {
	if entity == nil {
		return nil, errors.New("不支持 nil")
	}
	typeOf := reflect.TypeOf(entity)
	valueOf := reflect.ValueOf(entity)

	if valueOf.IsZero() {
		return nil, errors.New("不支持零值")
	}
	for typeOf.Kind() == reflect.Pointer {
		typeOf = typeOf.Elem()
		valueOf = valueOf.Elem()
	}
	if typeOf.Kind() != reflect.Struct {
		return nil, errors.New("不支持类型")
	}

	fieldCounts := typeOf.NumField()
	res := make(map[string]any, fieldCounts)
	for i := 0; i < fieldCounts; i++ {
		fieldType := typeOf.Field(i)
		fieldValue := valueOf.Field(i)
		if fieldType.IsExported() {
			res[fieldType.Name] = fieldValue.Interface()
		} else {
			res[fieldType.Name] = reflect.Zero(fieldType.Type).Interface()
		}
	}
	return res, nil
}

func SetFields(entity any, fieldName string, newVal any) error {
	val := reflect.ValueOf(entity)
	for val.Type().Kind() == reflect.Pointer {
		val = val.Elem()
	}
	field := val.FieldByName(fieldName)
	if !field.CanSet() {
		return errors.New("不可修改字段")
	}
	field.Set(reflect.ValueOf(newVal))
	return nil
}
